"use client"

import { useState } from "react"
import { ChevronDown, ChevronRight, Copy } from "lucide-react"
import { Button } from "@/components/ui/button"
import { Textarea } from "@/components/ui/textarea"
import { cn } from "@/lib/utils"
import Link from "next/link"

export default function JsonPathViewer() {
  const [jsonInput, setJsonInput] = useState<string>(`{
  "Result": {
    "FailureCode": 0,
    "StatusCode": 0,
    "UserInfo": {
      "EmployeeID": 1000,
      "EnterpriseAccount": "93189"
    }
  },
  "Value": {
    "totalCount": 1,
    "outlines": [{
      "id": "67d8e8735adebf0001390ad3",
      "tenantId": "93189",
      "userId": "1000",
      "sourceWorkflowId": "67d8e8725adebf0001390ad2",
      "workflowId": "67d8e8739bbe49357499ae14",
      "name": "发邮件test",
      "count": 13,
      "enabled": true,
      "description": "",
      "entryType": "AccountObj",
      "entryTypeName": "客户",
      "rangeEmployeeIds": [1000],
      "rangeCircleIds": [],
      "rangeGroupIds": [],
      "rangeRoleIds": [],
      "createdBy": "1000",
      "createTime": 1742268530677,
      "lastModifiedBy": "1000",
      "lastModifiedTime": 1742268530677,
      "externalFlow": 0,
      "singleInstanceFlow": 1,
      "isDeleted": false,
      "hasInstance": true,
      "linkAppEnable": false
    }]
  }
}`)
  const [parsedJson, setParsedJson] = useState<any>(null)
  const [error, setError] = useState<string>("")
  const [selectedPath, setSelectedPath] = useState<string>("")
  const [expandedPaths, setExpandedPaths] = useState<Set<string>>(new Set())

  const parseJson = () => {
    try {
      const parsed = JSON.parse(jsonInput)
      setParsedJson(parsed)
      setError("")

      // Expand all paths by default
      const newExpandedPaths = new Set<string>()

      // Helper function to recursively collect all paths
      const collectPaths = (obj: any, currentPath = "") => {
        if (obj === null || typeof obj !== "object") {
          return
        }

        if (currentPath) {
          newExpandedPaths.add(currentPath)
        }

        if (Array.isArray(obj)) {
          obj.forEach((item, index) => {
            const newPath = currentPath ? `${currentPath}[${index}]` : `[${index}]`
            newExpandedPaths.add(newPath)
            collectPaths(item, newPath)
          })
        } else {
          Object.keys(obj).forEach((key) => {
            const newPath = currentPath ? `${currentPath}.${key}` : key
            newExpandedPaths.add(newPath)
            collectPaths(obj[key], newPath)
          })
        }
      }

      collectPaths(parsed)
      setExpandedPaths(newExpandedPaths)
    } catch (err) {
      setError("Invalid JSON: " + (err as Error).message)
      setParsedJson(null)
    }
  }

  const toggleExpand = (path: string) => {
    const newExpandedPaths = new Set(expandedPaths)
    if (newExpandedPaths.has(path)) {
      newExpandedPaths.delete(path)
    } else {
      newExpandedPaths.add(path)
    }
    setExpandedPaths(newExpandedPaths)
  }

  const copyToClipboard = () => {
    if (selectedPath) {
      navigator.clipboard.writeText(selectedPath)
    }
  }

  const renderJsonNode = (node: any, path = "", isLast = true) => {
    if (node === null) {
      return (
        <div className="ml-6">
          <span className="cursor-pointer text-muted-foreground" onClick={() => setSelectedPath(path)}>
            null
          </span>
          {!isLast && ","}
        </div>
      )
    }

    if (typeof node === "object" && !Array.isArray(node)) {
      const keys = Object.keys(node)
      if (keys.length === 0) {
        return (
          <div className="ml-6">
            <span className="cursor-pointer" onClick={() => setSelectedPath(path)}>
              {"{}"}
            </span>
            {!isLast && ","}
          </div>
        )
      }

      const isExpanded = expandedPaths.has(path)

      return (
        <div className="ml-2">
          <div className="flex items-center cursor-pointer" onClick={() => toggleExpand(path)}>
            {isExpanded ? <ChevronDown className="h-4 w-4" /> : <ChevronRight className="h-4 w-4" />}
            <span
              className={cn("font-mono text-sm", path === selectedPath ? "bg-primary/20 rounded px-1" : "")}
              onClick={(e) => {
                e.stopPropagation()
                setSelectedPath(path)
              }}
            >
              {"{"}
            </span>
          </div>

          {isExpanded && (
            <div className="ml-4 border-l-2 border-muted pl-2">
              {keys.map((key, index) => (
                <div key={key} className="flex">
                  <span
                    className={cn(
                      "font-mono text-sm cursor-pointer mr-1",
                      `${path ? path + "." : ""}${key}` === selectedPath ? "bg-primary/20 rounded px-1" : "",
                    )}
                    onClick={() => setSelectedPath(`${path ? path + "." : ""}${key}`)}
                  >
                    "{key}":
                  </span>
                  {renderJsonNode(node[key], `${path ? path + "." : ""}${key}`, index === keys.length - 1)}
                </div>
              ))}
            </div>
          )}

          <div>
            <span
              className={cn("font-mono text-sm", path === selectedPath ? "bg-primary/20 rounded px-1" : "")}
              onClick={() => setSelectedPath(path)}
            >
              {"}"}
            </span>
            {!isLast && ","}
          </div>
        </div>
      )
    }

    if (Array.isArray(node)) {
      if (node.length === 0) {
        return (
          <div className="ml-6">
            <span className="cursor-pointer" onClick={() => setSelectedPath(path)}>
              {"[]"}
            </span>
            {!isLast && ","}
          </div>
        )
      }

      const isExpanded = expandedPaths.has(path)

      return (
        <div className="ml-2">
          <div className="flex items-center cursor-pointer" onClick={() => toggleExpand(path)}>
            {isExpanded ? <ChevronDown className="h-4 w-4" /> : <ChevronRight className="h-4 w-4" />}
            <span
              className={cn("font-mono text-sm", path === selectedPath ? "bg-primary/20 rounded px-1" : "")}
              onClick={(e) => {
                e.stopPropagation()
                setSelectedPath(path)
              }}
            >
              {"["}
            </span>
          </div>

          {isExpanded && (
            <div className="ml-4 border-l-2 border-muted pl-2">
              {node.map((item, index) => (
                <div key={index} className="flex">
                  <span
                    className={cn(
                      "font-mono text-sm cursor-pointer mr-1",
                      `${path}[${index}]` === selectedPath ? "bg-primary/20 rounded px-1" : "",
                    )}
                    onClick={() => setSelectedPath(`${path}[${index}]`)}
                  >
                    [{index}]:
                  </span>
                  {renderJsonNode(item, `${path}[${index}]`, index === node.length - 1)}
                </div>
              ))}
            </div>
          )}

          <div>
            <span
              className={cn("font-mono text-sm", path === selectedPath ? "bg-primary/20 rounded px-1" : "")}
              onClick={() => setSelectedPath(path)}
            >
              {"]"}
            </span>
            {!isLast && ","}
          </div>
        </div>
      )
    }

    // For primitive values
    return (
      <div className="ml-6">
        <span
          className={cn(
            "cursor-pointer font-mono text-sm",
            path === selectedPath ? "bg-primary/20 rounded px-1" : "",
            typeof node === "string" ? "text-green-600" : "",
            typeof node === "number" ? "text-blue-600" : "",
            typeof node === "boolean" ? "text-purple-600" : "",
          )}
          onClick={() => setSelectedPath(path)}
        >
          {typeof node === "string" ? `"${node}"` : String(node)}
        </span>
        {!isLast && ","}
      </div>
    )
  }

  return (
    <div className="container mx-auto py-8 max-w-4xl">
      <div className="flex justify-between items-center mb-6">
        <h1 className="text-2xl font-bold">JSON 路径查看器</h1>
        <div className="flex gap-2">
          <Link href="/new-viewer">
            <Button variant="outline">新版本</Button>
          </Link>
          <Button onClick={parseJson}>解析 JSON</Button>
        </div>
      </div>

      <div className="mb-4">
        <Textarea
          value={jsonInput}
          onChange={(e) => setJsonInput(e.target.value)}
          className="font-mono h-48"
          placeholder="在此粘贴 JSON..."
        />
      </div>

      {error && <div className="p-4 mb-4 bg-red-100 text-red-800 rounded">{error}</div>}

      {selectedPath && (
        <div className="p-4 mb-4 bg-muted rounded flex items-center justify-between">
          <div className="font-mono">{selectedPath}</div>
          <Button variant="outline" size="sm" onClick={copyToClipboard}>
            <Copy className="h-4 w-4 mr-2" />
            复制
          </Button>
        </div>
      )}

      {parsedJson && (
        <div className="p-4 bg-muted rounded overflow-auto max-h-[600px]">
          <div className="font-mono text-sm">{renderJsonNode(parsedJson)}</div>
        </div>
      )}
    </div>
  )
}

